﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using HandScreen.DataMining;
using System.Threading;
using System.Windows.Threading;
using System.Windows.Media.Animation;

namespace HandScreen.Views
{
    /// <summary>
    /// Interaction logic for VasttrafikView.xaml
    /// </summary>
    public partial class VasttrafikView : UserControl, IScrollable, ISuspendable
    {
        private String stopId;
        private Boolean sortByDepTime;

        private int updateInterval;

        private Boolean canScrollDown;

        private Boolean firstLoad = true;

        private Thread updater;

        public Boolean CanScrollDown()
        {
            return false;
            //return canScrollDown;
        }
        private Boolean canScrollUp;
        private bool alive;

        public Boolean CanScrollUp()
        {
            return false;
            //return canScrollUp;
        }

        public int UpdateInterval
        {
            get { return updateInterval; }
            set { updateInterval = value; }
        }

        public VasttrafikView(String stopId, Boolean sortByDepTime)
        {
            alive = true;
            this.sortByDepTime = sortByDepTime;
            this.stopId = stopId;
            updateInterval = 35000;
            InitializeComponent();
            updater = new Thread(dataMineVasttrafik);
            updater.Start();
        }

        private void dataMineVasttrafik()
        {
            Vasttrafik vtInfo = new Vasttrafik(stopId, sortByDepTime);//4490 lindholmen, 4090 korsvägen;
            while (alive)
            {
                vtInfo.update();
                this.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(
                    delegate()
                    {
                        updateVasttrafik(vtInfo);
                        Thread initialize = new Thread(initializeAfterData);
                        initialize.Start();
                    }
                ));
                try { Thread.Sleep(updateInterval); }
                catch (Exception e) { }
            }
        }

        private void initializeAfterData()
        {
            Thread.Sleep(500);
            this.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(
                    delegate()
                    {
                        scrollToPosition(scrollContainer.HorizontalOffset, scrollContainer.VerticalOffset);
                        routeField.Width = routeHidden.ActualWidth;
                        nextField.Width = nextHidden.ActualWidth;
                        thereafterField.Width = thereafterHidden.ActualWidth;
                    }
                ));
        }

        private void updateVasttrafik(Vasttrafik vtInfo)
        {
            for (int x = 5; x < containerGrid.Children.Count; x++)
            {
                containerGrid.Children.RemoveAt(5);
            }
            int rowCounter = 0;
            Boolean backAlternator = true;
            foreach (VTRoute route in vtInfo.Routes)
            {
                Border background = new Border();
                if (backAlternator)
                {
                    background.Background = Brushes.Black;
                }
                else
                {
                    background.Background = Brushes.Gray;
                }
                backAlternator = !backAlternator;
                containerGrid.Children.Add(background);

                RowDefinition newRow = new RowDefinition();
                newRow.Height = GridLength.Auto;
                containerGrid.RowDefinitions.Add(newRow);
                rowCounter++;

                Border routeBorder = new Border();
                routeBorder.CornerRadius = new CornerRadius(5);
                routeBorder.Margin = new Thickness(4, 2, 4, 2);
                routeBorder.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString(route.Background));

                TextBlock routeName = new TextBlock();
                routeName.Text = route.Name;
                routeName.Style = (Style)FindResource("routeName");
                routeName.Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString(route.Foreground));
                routeBorder.Child = routeName;
                containerGrid.Children.Add(routeBorder);

                TextBlock destination = new TextBlock();
                destination.Text = route.Destination;
                destination.Style = (Style)FindResource("routeDestination");
                containerGrid.Children.Add(destination);

                TextBlock via = new TextBlock();
                if (!route.Via.Equals(""))
                {
                    via.Text = "via " + route.Via;
                    via.Style = (Style)FindResource("routeVia");
                    containerGrid.Children.Add(via);
                }

                TextBlock next = new TextBlock();
                next.Text = route.NextTrip;
                next.Style = (Style)FindResource("routeNext");
                containerGrid.Children.Add(next);

                TextBlock nextNext = new TextBlock();
                nextNext.Text = route.NextNextTrip;
                nextNext.Style = (Style)FindResource("routeNextNext");
                containerGrid.Children.Add(nextNext);

                Grid.SetColumn(routeBorder, 0);
                Grid.SetColumn(destination, 1);
                Grid.SetColumn(via, 2);
                Grid.SetColumn(next, 3);
                Grid.SetColumn(nextNext, 4);

                Grid.SetRow(background, rowCounter);
                Grid.SetColumnSpan(background, 5);
                Grid.SetRow(routeBorder, rowCounter);
                Grid.SetRow(destination, rowCounter);
                Grid.SetRow(via, rowCounter);
                Grid.SetRow(next, rowCounter);
                Grid.SetRow(nextNext, rowCounter);
            }
        }

        public void scrollUp()
        {
            //scrollContainer.ScrollToVerticalOffset(scrollContainer.VerticalOffset - scrollContainer.ActualHeight * 0.80);
            scrollToPosition(scrollContainer.HorizontalOffset, scrollContainer.VerticalOffset - scrollContainer.ActualHeight * 0.80);
        }

        public void scrollDown()
        {
            //scrollContainer.ScrollToVerticalOffset(scrollContainer.VerticalOffset + scrollContainer.ActualHeight * 0.80);
            scrollToPosition(scrollContainer.HorizontalOffset, scrollContainer.VerticalOffset + scrollContainer.ActualHeight * 0.80);
        }

        private void scrollToPosition(double x, double y)
        {
            DoubleAnimation vertAnim = new DoubleAnimation();
            vertAnim.From = scrollContainer.VerticalOffset;
            vertAnim.To = y;
            vertAnim.DecelerationRatio = .2;
            vertAnim.Duration = new Duration(TimeSpan.FromMilliseconds(250));

            DoubleAnimation horzAnim = new DoubleAnimation();
            horzAnim.From = scrollContainer.HorizontalOffset;
            horzAnim.To = x;
            horzAnim.DecelerationRatio = .2;
            horzAnim.Duration = new Duration(TimeSpan.FromMilliseconds(300));

            Storyboard sb = new Storyboard();
            sb.Children.Add(vertAnim);
            sb.Children.Add(horzAnim);

            Storyboard.SetTarget(vertAnim, scrollContainer);
            Storyboard.SetTargetProperty(vertAnim, new PropertyPath(AniScrollViewer.CurrentVerticalOffsetProperty));
            Storyboard.SetTarget(horzAnim, scrollContainer);
            Storyboard.SetTargetProperty(horzAnim, new PropertyPath(AniScrollViewer.CurrentHorizontalOffsetProperty));

            sb.Begin();

            if (containerGrid.ActualHeight - scrollContainer.ActualHeight <= 0)
            {
                topFade.Visibility = System.Windows.Visibility.Hidden;
                canScrollUp = false;
                bottomFade.Visibility = System.Windows.Visibility.Hidden;
                canScrollDown = false;
            }
            else
            {
                if (y <= 0)
                {
                    topFade.Visibility = System.Windows.Visibility.Hidden;
                    canScrollUp = false;
                }
                else
                {
                    topFade.Visibility = System.Windows.Visibility.Visible;
                    canScrollUp = true;
                }
                if (y >= containerGrid.ActualHeight - scrollContainer.ActualHeight)
                {
                    bottomFade.Visibility = System.Windows.Visibility.Hidden;
                    canScrollDown = false;
                }
                else
                {
                    bottomFade.Visibility = System.Windows.Visibility.Visible;
                    canScrollDown = true;
                }
            }
        }

        public void suspend()
        {
            updater.Interrupt();
            alive = false;
        }
    }
}
